/**
requestOptions = {
        path: '',
        params: {},
        isLoading: false,	//请求中是否显示nprogress
        isToast: true, //失败情况是否显示message提示
        header: [], //请求头
        succ: (res) => {}, //业务成功,返回业务数据
        fail: (msg) => {}, //业务失败,返回错误消息
        failure: () => {}, //网络失败
        complete: () => {} //请求完成	
}
 */
import msg from '@ui/message.js'
import axios from 'axios'
import {
    BASE_URL
} from "./url.js"
import auth from './auth.js'
import progress from "../ui/nprogress"
import event from "@util/eventBus"

const SUCCESS = 0
const AUTH_FAIL = 1001

// const FORBIDDEN = 1002

const DEFAULT_TOAST = true
const DEFAULT_LOADING = false

function _isSuccess(code) {
    return code === SUCCESS
}

function _isAuthFail(code) {
    return code === AUTH_FAIL
}

function _getData(res) {
    return res.data.data
}

function _getMessage(res) {
    return res.data.msg
}

function _getCode(res) {
    return res.data.code
}


function _request(method, path, parameter, header) {
    let config = {
        url: path,
        method: method,
        baseURL: BASE_URL,
        headers: {
            ...header,
            'accessToken': auth.getToken()
        },
        // withCredentials: true,
    }
    if (method == "GET") {
        config.params = parameter
    } else if (method == "POST" || method == "PUT" || method == "PATCH" || method == "DELETE") {
        config.data = parameter
    }
    return axios.request(config)
}

function _callBack(source, funcName, targetData = null) {
    if (source != undefined &&
        funcName in source &&
        source[funcName] instanceof Function) {
        if (source.bind != undefined && source.bind != null) {
            source[funcName].call(source.bind, targetData)
        } else {
            source[funcName](targetData)
        }
    }
}

function _awaitResult(request, requestOptions) {
    var isToast = DEFAULT_TOAST
    if (requestOptions.isToast != null) {
        isToast = requestOptions.isToast
    }
    var isLoading = DEFAULT_LOADING
    if (requestOptions.isLoading != null) {
        isLoading = requestOptions.isLoading
    }

    if (isLoading) {
        progress.start()
    }

    request.then((res) => {
        const data = _getData(res)
        const code = _getCode(res)
        const message = _getMessage(res)

        if (_isSuccess(code)) {
            _callBack(requestOptions, 'succ', data)
        } else if (_isAuthFail(code)) {
            event.sendEvent("AUTH_FAIL")
            console.error('验证失败')
        } else {
            if (message != undefined && message != null && message.length > 0) {
                _callBack(requestOptions, 'fail', message)
                if (isToast) {
                    msg.error(message)
                }
            } else {
                _callBack(requestOptions, 'fail')
                if (isToast) {
                    msg.error('操作失败')
                }
            }
        }
        if (isLoading) {
            progress.done()
        }
        _callBack(requestOptions, 'complete')
    }).catch(err => {
        console.error(err)
        _callBack(requestOptions, 'failure')
        _callBack(requestOptions, 'complete')
        if (isLoading) {
            progress.done()
        }
    })
}

function GET(requestOptions) {
    _awaitResult(_request("GET", requestOptions.path, requestOptions.params, requestOptions.header),
        requestOptions)
}

function POST(requestOptions) {
    _awaitResult(_request("POST", requestOptions.path, requestOptions.params, requestOptions.header), requestOptions)
}

function UPLOAD(requestOptions) {
    _awaitResult(_request("POST", requestOptions.path, requestOptions.params, {
        'content-type': 'application/x-www-form-urlencoded',
        ...requestOptions.header
    }), requestOptions)
}

function PUT(requestOptions) {
    _awaitResult(_request("PUT", requestOptions.path, requestOptions.params, requestOptions.header), requestOptions)
}

function PATCH(requestOptions) {
    _awaitResult(_request("PATCH", requestOptions.path, requestOptions.params, requestOptions.header), requestOptions)
}

function DELETE(requestOptions) {
    _awaitResult(_request("DELETE", requestOptions.path, requestOptions.params, requestOptions.header), requestOptions)
}

export {
    GET,
    POST,
    UPLOAD,
    PUT,
    PATCH,
    DELETE
}